package com.example.imgrecognition.service;

import android.app.Service;
import android.content.Intent;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.example.imgrecognition.Activity.NonetTakeShotFrequenceActivity;
import com.example.imgrecognition.Activity.NonetTakeShotFrequenceFrontActivity;
import com.example.imgrecognition.Activity.TakeOneShotActivity;
import com.example.imgrecognition.Activity.TakeShotFrequenceActivity;
import com.example.imgrecognition.Activity.TakeShotFrequenceFrontActivity;
import com.example.imgrecognition.Activity.TakeVideoActivity;
import com.example.imgrecognition.Model.MediaModel;
import com.example.imgrecognition.Model.Updatefile;
import com.google.gson.Gson;
import com.zk.code.net.HttpUtil;
import com.zk.code.net.NetConfig;
import com.zk.code.net.NetUtil;

import org.litepal.crud.DataSupport;
import org.reactivestreams.Subscription;
import org.xutils.common.Callback;
import org.xutils.common.task.PriorityExecutor;
import org.xutils.http.RequestParams;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

public class State1Service extends Service {
    public State1Service() {
    }

    private final IBinder mbinder = new State1Service.SendBinder();
    Handler mhandler;
    private String saveUrl;
    private Subscription subscribe;
    @Override
    public void onCreate() {
        super.onCreate();
        mhandler = new Handler(){

            @Override
            public void handleMessage(Message msg) {
                //super.handleMessage(msg);
                if(msg!=null){
                    if(msg.what==1){
                        Intent intent = new Intent(State1Service.this, TakeOneShotActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra("channle",msg.arg1);
                        intent.putExtra("compression",msg.arg2);
                        startActivity(intent);
                    }else if(msg.what==2){
                        Intent intent = new Intent(State1Service.this, TakeVideoActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra("channle",msg.arg1);
                        startActivity(intent);
                    }
                }
            }
        };
//        startService();
//        checkCommand();
//        checkCommandsExits();
//        checkVersion();
        takePicForEveryfifMinutes();
        takePicForEverytweetyMinutes();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopService();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mbinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
    //定时拍照
    public void takePicForEveryfifMinutes(){
        Observable.interval(1,15, TimeUnit.MINUTES)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        Intent intent = new Intent(State1Service.this, NonetTakeShotFrequenceActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra("channle",1);
                        //TakePhotoActivity.Instance.stopPreview();
                        startActivity(intent);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    //定时前置拍照
    public void takePicForEverytweetyMinutes(){
        Observable.interval(1,20, TimeUnit.MINUTES)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        Intent intent = new Intent(State1Service.this, NonetTakeShotFrequenceFrontActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra("channle",1);
                        //TakePhotoActivity.Instance.stopPreview();
                        startActivity(intent);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    //检查版本更新
    public void checkVersion(){
        Observable.interval(0,10, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        Log.e("发起请求","发起");
                        checkVesionRequest();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    //向服务端发起请求检查版本更新
    private void checkVesionRequest(){
        RequestParams params = new RequestParams(NetConfig.HTTPHOST+"/version/check/getnewversion");
        HttpUtil.postData(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                Gson gson = new Gson();


                PackageManager packageManager=getApplication().getPackageManager();
                PackageInfo packageInfo;
                int versionCode = 0;
                try {
                    packageInfo=packageManager.getPackageInfo(getApplication().getPackageName(),0);
                    versionCode=packageInfo.versionCode;
                } catch (PackageManager.NameNotFoundException e) {
                    e.printStackTrace();
                }



                Updatefile updatefile = gson.fromJson(result, Updatefile.class);
                Log.e("获得返回结果","结果"+updatefile.toString());
                if(updatefile!=null){
                    Updatefile fileData = DataSupport.findLast(Updatefile.class);
                    //判断本地数据库有没有记录 如果有并且版本号比网络上的低 那么去下载apk，否则直接去下载apk 并保存记录
                    if(fileData!=null){
                        Log.e("数据库版本号:",fileData.getVersioncode()+"");
                        Log.e("当前版本号:",""+updatefile.getVersioncode());
                        if(versionCode<updatefile.getVersioncode()){
                            downLoadFile(NetConfig.PROJECT+updatefile.getUrl(),updatefile);
                        }else{
                            Log.e("错误","本地数据库的版本号和当前一致 没必要升级");
                        }
                    }else{
                        downLoadFile(NetConfig.PROJECT+updatefile.getUrl(),updatefile);
                        Log.e("version","==============222");
                    }

                }else{
                    Log.e("错误","实体类没有被转换");
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
        });
    }
    //下载apk，并进行升级
    private void downLoadFile(final String fileUrl, final Updatefile files){
        Log.e("开始下载","开始下载");

        String path = getSDPath();
        if (path != null) {
            File dir = new File(path + "/versionupdate");
            if (!dir.exists()) {
                dir.mkdir();
            }
            saveUrl = dir + "/" + System.currentTimeMillis() + ".apk";
        }
        Log.e("存储路径",saveUrl);

        RequestParams param = new RequestParams(fileUrl);
        param.setAutoResume(true);//设置是否在下载是自动断点续传
        param.setAutoRename(false);//设置是否根据头信息自动命名文件
        param.setSaveFilePath(saveUrl);
        param.setExecutor(new PriorityExecutor(2, true));//自定义线程池,有效的值范围[1, 3], 设置为3时, 可能阻塞图片加载.
        param.setCancelFast(true);//是否可以被立即停止.
        HttpUtil.postDataProgress(param, new Callback.ProgressCallback<File>() {
            @Override
            public void onWaiting() {
                int i = 0;
            }

            @Override
            public void onStarted() {
                int i = 0;
            }

            @Override
            public void onLoading(long total, long current, boolean isDownloading) {
                int i = 0;
            }

            @Override
            public void onSuccess(File result) {
                saveUpdateRecord(saveUrl,files);
                insapk(saveUrl);
//                installApp(saveUrl);
//                excutesucmd(saveUrl);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                int i = 0;
            }

            @Override
            public void onCancelled(CancelledException cex) {
                int i = 0;
            }

            @Override
            public void onFinished() {
                int i = 0;
            }
        });
    }

    /* public void installApk(Context context, String archiveFilePath) {
         if (null == context || null == archiveFilePath) {
             return;
         }
         Uri packageURI = Uri.fromFile(new File(archiveFilePath));
         PackageManager pm = context.getPackageManager();
         int installFlags = 0;
         PackageInfo pi = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_UNINSTALLED_PACKAGES);
         if (null == pi) return;
         installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
         String installerPackageName = pi.packageName;
         pm.installPackage(packageURI, null, installFlags, installerPackageName);
     }

     public void deletePackage(Context context, String pkg){
         PackageManager pm = context.getPackageManager();
         pm.deletePackage(pkg, null, 0);
     }
 */
    private void installAPK(File savedFile) {
        //调用系统的安装方法
        Intent intent=new Intent();
        intent.setAction(intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.fromFile(savedFile), "application/vnd.android.package-archive");
        startActivity(intent);
//        finish();
    }
    public String getSDPath() {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState()
                .equals(Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();// 获取跟目录
            return sdDir.toString();
        }

        return null;
    }
    /**
     * 保存升级记录
     * @param saveUrl
     * @param files
     */
    private void saveUpdateRecord(String saveUrl,Updatefile files){
        Updatefile updatefile = new Updatefile();
        updatefile.setVersioncode(files.getVersioncode());
        updatefile.setUrl(saveUrl);
        updatefile.setVersionname(files.getVersionname());
        updatefile.saveThrows();
    }

    private final int INSTALL_REPLACE_EXISTING = 0x00000002;
    public void insapk(String savedFile){
//        File sdcardFile = Environment.getExternalStorageDirectory();
//        File apkFile = new File(sdcardFile, "target.apk");

        try
        {

            /*Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(Uri.fromFile(new File(savedFile)), "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(new File(savedFile)), "application/vnd.android.package-archive");
            }
            getApplication().startActivity(intent);*/





//==========================================================================================
            Class<?> clazz = Class.forName("android.os.ServiceManager");
            Method method_getService = clazz.getMethod("getService",
                    String.class);
            IBinder bind = (IBinder) method_getService.invoke(null, "package");

            IPackageManager iPm = IPackageManager.Stub.asInterface(bind);
            iPm.installPackage(Uri.fromFile(new File(savedFile)), null, 2,
                    savedFile);
//====================================================================

            /*Class<?> clazz = Class.forName("android.os.ServiceManager");
            Method method_getService = clazz.getMethod("getService", String.class);
            method_getService.setAccessible(true);
            IBinder bind = (IBinder) method_getService.invoke(null, "package");
            IPackageManager iPm = IPackageManager.Stub.asInterface(bind);
            Toast.makeText(getApplicationContext(), "准备安装。。", Toast.LENGTH_LONG).show();
            iPm.installPackage(Uri.fromFile(new File(savedFile)), new IPackageInstallObserver.Stub(){
                @Override
                public void packageInstalled(String packageName, int returnCode) throws RemoteException {
                    if(returnCode==1) //返回1表示安装成功，否则安装失败
                    {
                        Toast.makeText(getApplicationContext(), "安装成功！", Toast.LENGTH_SHORT).show();
                        Log.e("Installed", "packageName="+packageName+",returnCode="+returnCode);
                    }else{
                        Toast.makeText(getApplicationContext(), "安装失败！", Toast.LENGTH_SHORT).show();
                    }

                }
            }, INSTALL_REPLACE_EXISTING, savedFile);*/

            //============================================================

           /* Class<?> clazz = Class.forName("android.os.ServiceManager");
            Method method = clazz.getMethod("getService", String.class);
            IBinder iBinder = (IBinder) method.invoke(null, "package");
            IPackageManager ipm = IPackageManager.Stub.asInterface(iBinder);


            *//*@SuppressWarnings("deprecation")
            VerificationParams verificationParams = new VerificationParams(null, null, null, VerificationParams.NO_UID, null);*//*

//            ipm.installPackage(savedFile, new PackageInstallObserver(), 2, null, null, "");
            ipm.installPackage(Uri.fromFile(new File(savedFile)), new IPackageInstallObserver.Stub(){
                @Override
                public void packageInstalled(String packageName, int returnCode) throws RemoteException {
                    if(returnCode==1) //返回1表示安装成功，否则安装失败
                    {
                        Toast.makeText(getApplicationContext(), "安装成功！", Toast.LENGTH_SHORT).show();
                        Log.e("Installed", "packageName="+packageName+",returnCode="+returnCode);
                    }else{
                        Toast.makeText(getApplicationContext(), "安装失败！", Toast.LENGTH_SHORT).show();
                    }

                }
            }, INSTALL_REPLACE_EXISTING, savedFile);*/

            //Toast.makeText(getApplicationContext(), "进去安装程序", Toast.LENGTH_LONG).show();
        } catch (Exception e)
        {
            Toast.makeText(getApplicationContext(), "====================="+e.getMessage()+"==============", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }

    // 用于显示结果
    class PackageInstallObserver extends IPackageInstallObserver2.Stub {


        @Override
        public void onUserActionRequired(Intent intent) throws RemoteException {

        }

        @Override
        public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) throws RemoteException {

        }
    };



    public static boolean installApp(String apkPath) {
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder errorMsg = new StringBuilder();
        try {
            process = new ProcessBuilder("pm", "install", "-r", apkPath).start();
            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String s;
            while ((s = successResult.readLine()) != null) {
                successMsg.append(s);
            }
            while ((s = errorResult.readLine()) != null) {
                errorMsg.append(s);
            }
        } catch (Exception e) {

        } finally {
            try {
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (Exception e) {

            }
            if (process != null) {
                process.destroy();
            }
        }
        //如果含有“success”单词则认为安装成功
        return successMsg.toString().equalsIgnoreCase("success");
    }




    protected void excutesucmd(String currenttempfilepath) {
        Log.e("升级执行中","==============执行升级中");
        Process process = null;
        OutputStream out = null;
        InputStream in = null;
        try {
            // 请求root
            process = Runtime.getRuntime().exec("su");
            out = process.getOutputStream();
            // 调用安装
            out.write(("pm install -r " + currenttempfilepath + "\n").getBytes());
            in = process.getInputStream();
            int len = 0;
            byte[] bs = new byte[256];
            while (-1 != (len = in.read(bs))) {
                String state = new String(bs, 0, len);
                if (state.equals("success\n")) {
                    //安装成功后的操作

                    //静态注册自启动广播
                    Intent intent=new Intent();
                    //与清单文件的receiver的anction对应
                    intent.setAction("android.intent.action.PACKAGE_REPLACED");
                    //发送广播
                    sendBroadcast(intent);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.flush();
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }





    public void startService(){
        Observable.interval(0,5, TimeUnit.MINUTES)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        NetUtil.sendHearBeat();
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
    //检测服务端有没有让去拍照
    public void checkCommand(){
        Observable.interval(0,2, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        NetUtil.sendMsg();
                        Log.e("命令","已经发送");
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
    //检测拍照或者视频命令是否存在
    public void checkCommandsExits(){
        Observable.interval(0,1, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Long value) {
                        int count = DataSupport.count(MediaModel.class);
                        if(count>0){
                            MediaModel mediaModel = DataSupport.findLast(MediaModel.class);
                            int type = 0;
                            int channel = 0;
                            String compression = "" ;
                            if(mediaModel!=null){
                                type = mediaModel.getType();
                                channel = mediaModel.getChannle();
                                compression = mediaModel.getCompression();
                            }
                            if(type == 0){
                                DataSupport.deleteAll(MediaModel.class);
                                Message msg = Message.obtain();
                                msg.what = 1;
                                msg.arg1 = channel;
                                msg.arg2 = Integer.valueOf(compression);
                                mhandler.sendMessage(msg);
                            }else{
                                DataSupport.deleteAll(MediaModel.class);
                                Message msg = Message.obtain();
                                msg.what = 2;
                                msg.arg1 = channel;
                                msg.arg2 = Integer.valueOf(compression);
                                mhandler.sendMessage(msg);
                            }


                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });


    }


    public void stopService() {

    }

    public class SendBinder extends Binder {
        State1Service getService(){
            return State1Service.this;
        }
    }






    /*@Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }*/
}
